package org.zero.concurrency.demo.example.aqs;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

/**
 * @program: concurrency-demo
 * @description:
 * @author: 01
 * @create: 2018-10-19 10:56
 **/
@Slf4j
public class CyclicBarrierExample2 {
    // 给定一个值，说明有多少个线程同步等待
    private static CyclicBarrier barrier = new CyclicBarrier(5);

    public static void main(String[] args) throws InterruptedException {
        ExecutorService exec = Executors.newCachedThreadPool();

        for (int i = 0; i < 10; i++) {
            final int num = i;
            // 延迟1秒，方便观察
            Thread.sleep(1000);
            exec.execute(() -> {
                try {
                    CyclicBarrierExample2.race(num);
                } catch (Exception e) {
                    log.error("", e);
                }
            });
        }
        exec.shutdown();
    }

    private static void race(int num) throws Exception {
        Thread.sleep(1000);
        log.info("{} is ready", num);
        try {
            //  由于状态可能会改变，所以会抛出BarrierException异常，如果想继续往下执行，需要加上try-catch
            barrier.await(2000, TimeUnit.MILLISECONDS);
        } catch (InterruptedException | TimeoutException | BrokenBarrierException e) {
            log.warn("exception occurred {} {}. isBroken : {}", e.getClass().getName(), e.getMessage(), barrier.isBroken());
        }
        log.info("{} continue", num);
    }
}
